package ControlLayer;
import ModelLayer.*;
import java.util.Set;
import java.util.Iterator;
import java.util.HashSet;
/**
 * This class is used for controlling all things which have to do with an item or with the container.
 * 
 * @author Group1
 * @version 2011-06-05
 */
public class ItemController
{
    private ItemContainer itemContainer;
    private SupplierController supplierController;

    /**
     * Creates or gets an instance of the itemContainer and supplierController.
     */
    public ItemController()
    {
        itemContainer = ItemContainer.getInstance();
        supplierController = new SupplierController();
    }
    
    /**
     * Creates an barcode and item and add them to the container (HashMap).
     * @param barcode Barcode of the item
     * @param itemNumber The item number of the item
     * @param name Name of the item
     * @param amountPrOrder This is the amount you will get from the supplier when you order one.
     * @param description Description of the item
     * @param buyingPrice The price the company has to pay for the item
     * @param sellingPrice The price of the item when the company wants to sell it
     * @param locationNumber The location where the item is stored. (Byggecenter, traelast, or both places)
     * @param supplier The supplier of the item
     * @param amountInStock The amount of the item which the company has in stock
     * @param minStock The minimum amount the company wants to have in stock
     * @param maxStock The maximum amount the company wants to have in stock
     */
    public void createItem(String barcode, String itemNumber, String name, int amountPrOrder, String description, int buyingPrice, int sellingPrice,
                           String locationNumber, Supplier supplier, int amountInStock, int minStock, int maxStock)
    {
        Item newItem = new Item(buyingPrice, sellingPrice, itemNumber, name, amountPrOrder, 0, locationNumber, description, supplier, amountInStock, minStock, maxStock);
        newItem.setBarcode(barcode);
        itemContainer.createItem(barcode, newItem);
    }
     
    /**
     * Search for an item by barcode.
     * @return item if the barcode is found else returns null
     */
    public Item findItemByBarcode(String searchBarcode)
    {
        return itemContainer.findItemByBarcode(searchBarcode);
    }
    
    /**
     * Search for an item by item number.
     * @return item if the item number is found else returns null
     */
    public Item findItemByItemNumber(String searchItemNumber)
    {
        return itemContainer.findItemByItemNumber(searchItemNumber);
    }
    
    /**
     * Deletes an item.
     * @param barcode The barcode of the item you want to delete
     * @return boolean Returns true if item is deleted, if not, return false
     */
    public boolean deleteItem(String barcode)
    {
        if(itemContainer.findItemByBarcode(barcode) != null)
        {
            itemContainer.deleteItem(barcode);
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * Change discount of an item.
     * @param searchBarcode Barcode of the item
     * @param newDiscount New discount at the item
     * @return boolean Returns true if item is found and discount is changed else return false
     */
    public boolean updateItemDiscount(String searchBarcode, int newDiscount)
    {
        Item item = itemContainer.findItemByBarcode(searchBarcode);
        if(item != null)
        {
            item.setDiscount(newDiscount);
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * Change the description of an item.
     * @param searchBarcode Barcode of the item
     * @param newDescription The new description of the item
     * @return boolean Returns true if item is found and description is changed else return false
     */
    public boolean updateItemDescription(String searchBarcode, String newDescription)
    {
        Item item = itemContainer.findItemByBarcode(searchBarcode);
        if(item != null)
        {
            item.setDescription(newDescription);
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * Change buy and sell price
     * @param searchBarcode Barcode of the item
     * @param newBuyingPrice New buying price when the company has to buy the item from the supplier
     * @param newSellingPrice New salesprice when the company wnats to sell the item
     * @return boolean Returns true if item is found and prices are changed else return false
     * 
     */
    public boolean updateItemBuySell(String searchBarcode, int newBuyingPrice, int newSellingPrice)
    {
        Item item = itemContainer.findItemByBarcode(searchBarcode);
        if(item != null)
        {
            item.setBuyingPrice(newBuyingPrice);
            item.setSellingPrice(newSellingPrice);
            return true;
        }
        else
        {
           return false; 
        }
    }
    
    /**
     * Change location for the item
     * @param searchBarcode Barcode of the item
     * @param newLocationNumber The new location for the item
     * @return boolean Returns true if item is found and location is changed else return false
     */
    public boolean updateItemLocation(String searchBarcode, String newLocationNumber)
    {
        Item item = itemContainer.findItemByBarcode(searchBarcode);
        if(item != null)
        {
            item.setLocationsNumber(newLocationNumber);
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * Change the amount pr order.
     * @param searchBarcode Barcode of the item
     * @param newAmountPrOrder The new amount which is delivered from the supplier when the company order one
     * @return boolean Returns true if item is found and new amount pr order is changed else return false
     */
    public boolean updateAmountPrOrder(String searchBarcode, int newAmountPrOrder)
    {   
        Item item = itemContainer.findItemByBarcode(searchBarcode);
        if(item != null)
        {
            item.setAmountPrOrder(newAmountPrOrder);
            return true;
        }
        else
        {
            return false;
        }
        
    }
    
    /**
     * Change the supplier.
     * @param searchBarcode Barcode of the item
     * @param name Name of the supplier
     * @return boolean Returns true if item and supplier are found and supplier is changed else return false and throws an exception.
     */
    public boolean updateItemSupplier(String name, String searchBarcode) throws Exception
    {
        if(supplierController.findSupplier(name) != null && itemContainer.findItemByBarcode(searchBarcode) != null)
        {
            Supplier supplier = supplierController.findSupplier(name);
        
            Item item = itemContainer.findItemByBarcode(searchBarcode);
        
            item.setSupplier(supplier);
            
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /**
     * Adds a supplier to an item.
     * @param nameOnSupplier The name of the Supplier
     * @return Supplier or null
     */
    public Supplier addSupplier(String nameOnSupplier)
    {
        if(supplierController.findSupplier2(nameOnSupplier) != null)
        {
           Supplier supplier = supplierController.findSupplier2(nameOnSupplier);
           return supplier;
        }
        else
        {
            return null;
        }
    }
    
    /**
     * Creates an supplier by the supplierController.
     * @param nameSupplier Name of the supplier
     * @param addressSuppier Address of the supplier
     * @param citySupplier City of the supplier
     * @param ZIPCodeSupplier ZIP code of the supplier
     * @param phoneNumberSupplier Phone number of the supplier
     * @param deliveryTimeSupplier Delivery time - how long its going to take to deliver orders
     */
    public void createSupplier(String nameSupplier, String addressSupplier, String citySupplier, int ZIPCodeSupplier, int phoneNumberSupplier, String deliveryTimeSupplier)
    {
        supplierController.createSupplier(nameSupplier, addressSupplier, citySupplier, ZIPCodeSupplier, phoneNumberSupplier, deliveryTimeSupplier);
    }
    
    /**
     * Returns a Set with alle the keys (barcodes)
     * @return set Set of keys
     */
    public Set<String> listOfItems()
    {
        Set<String> keys = itemContainer.getItemContainer().keySet();
        return keys;
    }
    
    /**
     * Returns a HashSet with items which is under the minimum stock value.
     * return HashSet a set of barcodes
     */
    public HashSet<String> itemsToOrderBySupplier()
    {
        Iterator it = itemContainer.getItemContainer().keySet().iterator();
        HashSet<String> keys;
        keys = new HashSet<String>();
        while(it.hasNext())
        {
            Item item = itemContainer.getItemContainer().get(it.next());
        
            if(item.getAmountInStock() < item.getMinStock() && item.getOrderedBySupplier() == false)
            {
                keys.add(item.getBarcode());
            }
        }
        return keys;
    }
    
    /**
     * Updates stock when a new delivery arives from the supplier
     * @param barcode Barcode of the item which is delivered
     * @param amountDelivered The amount which the company has recieved from the supplier
     */
    public void updateStockNewDelivery(String barcode, int amountDelivered)
    {
        Item item = itemContainer.findItemByBarcode(barcode);
        
        item.setAmountInStock(item.getAmountInStock() + amountDelivered);
        item.setOrderedBySupplier(false);
    }
}